package controller

import (
	"errors"
	"fmt"
	"go-gateway-learn/dao"
	"go-gateway-learn/dto"
	"go-gateway-learn/middleware"
	"go-gateway-learn/public"
	"strings"
	"time"

	"go-gateway-learn/golang_common/lib"

	"github.com/gin-gonic/gin"
)

type ServiceController struct {
}

func ServiceRegister(routerGroup *gin.RouterGroup) {
	service := &ServiceController{}
	routerGroup.GET("/list", service.ServiceList)
	routerGroup.GET("/del", service.ServiceDel)
	routerGroup.POST("/addhttp", service.ServiceAddHTTP)
	routerGroup.POST("/updatehttp", service.ServiceUpdateHTTP)
	routerGroup.GET("/detail", service.ServiceDetail)
	routerGroup.GET("/stat", service.ServiceStat)

	routerGroup.POST("/updatetcp", service.ServiceUpdateTCP)
	routerGroup.GET("/addtcp", service.ServiceAddTCP)

	routerGroup.POST("/updategrpc", service.ServiceUpdateGRPC)
	routerGroup.GET("/addgrpc", service.ServiceAddGRPC)
}

// ServiceList godoc
// @Summary 服务列表
// @Description 服务信息获取
// @Tags 服务管理
// @ID /service/list
// @Accept  json
// @Produce  json
// @Param info query string false "关键词"
// @Param page_no query int true "页码"
// @Param page_size query int true "每页行数"
// @Success 200 {object} middleware.Response{data=dto.ServiceListOutput} "success"
// @Router /service/list [GET]
func (serviceList *ServiceController) ServiceList(c *gin.Context) {
	param := &dto.ServiceListInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}

	serviceInfo := &dao.ServiceInfo{}
	list, total, err := serviceInfo.PageList(c, db, param)
	if err != nil {
		middleware.ResponseError(c, 2002, err)
		return
	}

	outList := []dto.ServiceListItemOutput{}
	for _, listItem := range list {
		serviceDetail, err := listItem.ServiceDetail(c, db, &listItem)
		if err != nil {
			middleware.ResponseError(c, 2003, err)
			return
		}
		serviceAddr := "unknow"
		clusterIP := lib.GetStringConf("base.cluster.clusterIP")
		clusterPort := lib.GetStringConf("base.cluster.clusterPort")
		clusterSSLPort := lib.GetStringConf("base.cluster.clusterSSLPort")
		switch serviceDetail.Info.LoadType {
		case public.LoadTypeHTTP:
			if serviceDetail.HTTPRule.RuleType == public.HTTPRuleTypePrefixURL {
				if serviceDetail.HTTPRule.NeedHttps == 1 {
					serviceAddr = fmt.Sprintf("%s:%s%s", clusterIP, clusterSSLPort, serviceDetail.HTTPRule.Rule)
				} else if serviceDetail.HTTPRule.NeedHttps == 0 {
					serviceAddr = fmt.Sprintf("%s:%s%s", clusterIP, clusterPort, serviceDetail.HTTPRule.Rule)
				}
			} else if serviceDetail.HTTPRule.RuleType == public.HTTPRuleTypeDomain {
				serviceAddr = serviceDetail.HTTPRule.Rule
			}
		case public.LoadTypeTCP:
			serviceAddr = fmt.Sprintf("%s:%d", clusterIP, serviceDetail.TCPRule.Port)
		case public.LoadTypeGRPC:
			serviceAddr = fmt.Sprintf("%s:%d", clusterIP, serviceDetail.GRPCRule.Port)
		}

		ipList := serviceDetail.LoadBalance.GetIPListByModel()
		counter, err := public.FlowCounterHandler.GetCounter(public.FlowServicePrefix+listItem.ServiceName)
		if err != nil {
			middleware.ResponseError(c, 2004, err)
			return
		}
		outItem := dto.ServiceListItemOutput{
			ID:          int64(listItem.ID),
			ServiceName: listItem.ServiceName,
			ServiceDesc: listItem.ServiceDesc,
			ServiceAddr: serviceAddr,
			LoadType:    listItem.LoadType,
			Qps:         counter.QPS,
			Qpd:         counter.TotalCount,
			TotalNodes:  len(ipList),
		}
		outList = append(outList, outItem)
	}
	out := &dto.ServiceListOutput{
		Total: total,
		List:  outList,
	}
	middleware.ResponseSuccess(c, out)
}

// ServiceDel godoc
// @Summary 删除服务
// @Description 删除服务信息
// @Tags 服务管理
// @ID /service/del
// @Accept  json
// @Produce  json
// @Param ID query string false "关键词"
// @Param id query int true "ID"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router /service/del [GET]
func (serviceList *ServiceController) ServiceDel(c *gin.Context) {
	param := &dto.ServiceDelInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}
	serviceInfo := &dao.ServiceInfo{ID: param.ID}
	serviceInfo, err = serviceInfo.Find(c, db, serviceInfo)
	if err != nil {
		middleware.ResponseError(c, 2002, err)
		return
	}

	serviceInfo.IsDelete = 1
	if err := serviceInfo.Save(c, db); err != nil {
		middleware.ResponseError(c, 2003, err)
		return
	}
	middleware.ResponseSuccess(c, "")
}

// ServiceAddHTTP godoc
// @Summary 添加HTTP服务
// @Description 添加HTTP服务
// @Tags 服务管理
// @ID /service/addhttp
// @Accept  json
// @Produce  json
// @Param body body dto.ServiceAddHTTPInput true "body"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router  /service/addhttp [post]
func (serviceaddhttp *ServiceController) ServiceAddHTTP(c *gin.Context) {
	param := &dto.ServiceAddHTTPInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}

	serviceInfo := &dao.ServiceInfo{ServiceName: param.ServiceName}
	if _, err = serviceInfo.Find(c, db, serviceInfo); err != nil {
		middleware.ResponseError(c, 2002, errors.New("服务已经存在"))
		return
	}

	httpUrl := &dao.HttpRule{RuleType: param.RuleType, Rule: param.Rule}
	if _, err = httpUrl.Find(c, db, httpUrl); err != nil {
		middleware.ResponseError(c, 2003, errors.New("服务接入前缀已经存在"))
		return
	}

	if len(strings.Split(param.IPList, "\n")) != len(strings.Split(param.WeightList, "\n")) {
		middleware.ResponseError(c, 2004, errors.New("IP列表和权重列表不一致"))
		return
	}
	tx := db.Begin()
	service := &dao.ServiceInfo{
		ServiceName: param.ServiceName,
		ServiceDesc: param.ServiceDesc,
	}
	if err := service.Save(c, tx); err != nil {
		db.Rollback()
		middleware.ResponseError(c, 2005, err)
		return
	}
	httpRule := &dao.HttpRule{
		ServiceID:      service.ID,
		RuleType:       param.RuleType,
		Rule:           param.Rule,
		NeedHttps:      param.NeedHTTPS,
		NeedStripUri:   param.NeedStripUri,
		NeedWebsocket:  param.NeedWebsocket,
		UrlRewrite:     param.UrlRewrite,
		HeaderTransfor: param.HeaderTransfor,
	}
	if err := httpRule.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2006, err)
		return
	}
	accessControl := &dao.AccessControl{
		ServiceID:         service.ID,
		OpenAuth:          param.OpenAuth,
		BlackList:         param.BlackList,
		WhiteList:         param.WhiteList,
		ClientIPFlowLimit: param.ClientIPFlowLimit,
		ServiceFlowLimit:  param.ServiceFlowLimit,
	}
	if err := accessControl.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2007, err)
		return
	}

	loadBalance := &dao.LoadBalance{
		ServiceID:              service.ID,
		RoundType:              param.RoundType,
		IPList:                 param.IPList,
		WeightList:             param.WeightList,
		UpstreamConnectTimeout: param.UpstreamConnectTimeout,
		UpstreamIdleTimeout:    param.UpstreamIdleTimeout,
		UpstreamMaxIdle:        param.UpstreamMaxIdle,
	}
	if err := loadBalance.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2008, err)
		return
	}
	if tx.Error == nil {
		tx.Commit()
	} else {
		tx.Rollback()
		middleware.ResponseError(c, 2009, tx.Error)
		return
	}
	middleware.ResponseSuccess(c, "")
}

// ServiceUpdateHTTP godoc
// @Summary 修改HTTP服务
// @Description 修改HTTP服务
// @Tags 服务管理
// @ID /service/updatehttp
// @Accept  json
// @Produce  json
// @Param body body dto.ServiceUpdateHTTPInput true "body"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router  /service/updatehttp [post]
func (service *ServiceController) ServiceUpdateHTTP(c *gin.Context) {
	param := &dto.ServiceUpdateHTTPInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}
	if len(strings.Split(param.IPList, "\n")) != len(strings.Split(param.WeightList, "\n")) {
		middleware.ResponseError(c, 2004, errors.New("IP列表和权重列表不一致"))
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}

	// Begin transaction
	tx := db.Begin()
	serviceInfo := &dao.ServiceInfo{ServiceName: param.ServiceName}
	serviceInfo, err = serviceInfo.Find(c, tx, serviceInfo)
	if err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2002, errors.New("服务不存在"))
		return
	}

	serviceDetail, err := serviceInfo.ServiceDetail(c, tx, serviceInfo)
	if err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2003, errors.New("服务不存在"))
		return
	}

	info := serviceDetail.Info
	info.ServiceDesc = param.ServiceDesc
	if err := info.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2005, err)
		return
	}

	httpRule := serviceDetail.HTTPRule
	httpRule.NeedHttps = param.NeedHTTPS
	httpRule.NeedStripUri = param.NeedStripUri
	httpRule.NeedWebsocket = param.NeedWebsocket
	httpRule.UrlRewrite = param.UrlRewrite
	httpRule.HeaderTransfor = param.HeaderTransfor
	if err := httpRule.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2006, err)
		return
	}

	accessControl := serviceDetail.AccessControl
	accessControl.OpenAuth = param.OpenAuth
	accessControl.BlackList = param.BlackList
	accessControl.WhiteList = param.WhiteList
	accessControl.ClientIPFlowLimit = param.ClientIPFlowLimit
	accessControl.ServiceFlowLimit = param.ServiceFlowLimit
	if err := accessControl.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2007, err)
		return
	}

	loadbalance := serviceDetail.LoadBalance
	loadbalance.RoundType = param.RoundType
	loadbalance.IPList = param.IPList
	loadbalance.WeightList = param.WeightList
	loadbalance.UpstreamConnectTimeout = param.UpstreamConnectTimeout
	loadbalance.UpstreamHeaderTimeout = param.UpstreamHeaderTimeout
	loadbalance.UpstreamIdleTimeout = param.UpstreamIdleTimeout
	loadbalance.UpstreamMaxIdle = param.UpstreamMaxIdle
	if err := loadbalance.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2008, err)
		return
	}

	if tx.Error == nil {
		tx.Commit()
	} else {
		tx.Rollback()
		middleware.ResponseError(c, 2009, tx.Error)
		return
	}
	middleware.ResponseSuccess(c, "")
}

// ServiceDetail godoc
// @Summary 服务详情
// @Description 服务信息详情
// @Tags 服务管理
// @ID /service/detail
// @Accept  json
// @Produce  json
// @Param id query int true "ID"
// @Success 200 {object} middleware.Response{data=dao.ServiceDetail} "success"
// @Router /service/detail [GET]
func (service *ServiceController) ServiceDetail(c *gin.Context) {
	param := &dto.ServiceDelInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}
	serviceInfo := &dao.ServiceInfo{ID: param.ID}
	serviceInfo, err = serviceInfo.Find(c, db, serviceInfo)
	if err != nil {
		middleware.ResponseError(c, 2002, err)
		return
	}

	serviceDetail, err := serviceInfo.ServiceDetail(c, db, serviceInfo)
	if err != nil {
		middleware.ResponseError(c, 2003, err)
		return
	}
	middleware.ResponseSuccess(c, serviceDetail)
}

// ServiceStat godoc
// @Summary 服务统计
// @Description 服务统计
// @Tags 服务管理
// @ID /service/stat
// @Accept  json
// @Produce  json
// @Param id query int true "ID"
// @Success 200 {object} middleware.Response{data=dto.ServiceStatOutput} "success"
// @Router /service/stat [GET]
func (service *ServiceController) ServiceStat(c *gin.Context) {
	param := &dto.ServiceDelInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}
	serviceInfo := &dao.ServiceInfo{ID: param.ID}
	serviceInfo, err = serviceInfo.Find(c, db, serviceInfo)
	if err != nil {
		middleware.ResponseError(c, 2002, err)
		return
	}

	serviceDetail_, err := serviceInfo.ServiceDetail(c, db, serviceInfo)
	if err != nil {
		middleware.ResponseError(c, 2003, err)
		return
	}

	counter, err := public.FlowCounterHandler.GetCounter(public.FlowServicePrefix + serviceDetail_.Info.ServiceName)
	if err != nil {
		middleware.ResponseError(c, 2004, err)
		return
	}
	todayList := []int64{}
	currentTime := time.Now()
	for i := 0; i <= time.Now().Hour(); i++ {
		dateTime:=time.Date(currentTime.Year(),currentTime.Month(),currentTime.Day(),i,0,0,0,lib.TimeLocation)
		hourData,_:=counter.GetHourData(dateTime)
		todayList = append(todayList, hourData)
	}

	yesterdayList := []int64{}
	yesterTime := currentTime.Add(-1*time.Duration(time.Hour*24))
	for i := 0; i <= 23; i++ {
		dateTime:=time.Date(yesterTime.Year(),yesterTime.Month(),yesterTime.Day(),i,0,0,0,lib.TimeLocation)
		hourData,_:=counter.GetHourData(dateTime)
		yesterdayList = append(yesterdayList, hourData)
	}
	middleware.ResponseSuccess(c, &dto.ServiceStatOutput{
		Today:     todayList,
		Yesterday: yesterdayList,
	})
}

// ServiceUpdateTCP godoc
// @Summary 修改TCP服务
// @Description 修改TCP服务
// @Tags 服务管理
// @ID /service/updatetcp
// @Accept  json
// @Produce  json
// @Param body body dto.ServiceUpdateTCPInput true "body"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router  /service/updatetcp [post]
func (service *ServiceController) ServiceUpdateTCP(c *gin.Context) {
	param := &dto.ServiceUpdateTCPInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	if len(strings.Split(param.IPList, "\n")) != len(strings.Split(param.WeightList, "\n")) {
		middleware.ResponseError(c, 2001, errors.New("IP列表和权重列表不一致"))
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2002, err)
		return
	}

	serviceTCP := &dao.ServiceInfo{ID: param.ID}
	servicTCPDetail, err := serviceTCP.ServiceDetail(c, db, serviceTCP)
	if err == nil {
		middleware.ResponseError(c, 2003, err)
		return
	}

	tx := db.Begin()
	info := servicTCPDetail.Info
	info.ServiceDesc = param.ServiceDesc
	if err := info.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2004, err)
		return
	}

	loadBalance := &dao.LoadBalance{}
	if servicTCPDetail.LoadBalance != nil {
		loadBalance = servicTCPDetail.LoadBalance
	}
	loadBalance.ServiceID = info.ID
	loadBalance.RoundType = param.RoundType
	loadBalance.IPList = param.IPList
	loadBalance.WeightList = param.WeightList
	loadBalance.ForbidList = param.ForbidList
	if err := loadBalance.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2005, err)
		return
	}

	tcpRule := &dao.TcpRule{}
	if servicTCPDetail.TCPRule != nil {
		tcpRule = servicTCPDetail.TCPRule
	}
	tcpRule.ServiceID = info.ID
	tcpRule.Port = param.Port
	if err := tcpRule.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2006, err)
		return
	}

	accessControl := &dao.AccessControl{}
	if servicTCPDetail.AccessControl != nil {
		accessControl = servicTCPDetail.AccessControl
	}
	accessControl.ServiceID = info.ID
	accessControl.OpenAuth = param.OpenAuth
	accessControl.BlackList = param.BlackList
	accessControl.WhiteList = param.WhiteList
	accessControl.WhiteHostName = param.WhiteHostName
	accessControl.ClientIPFlowLimit = param.ClientIPFlowLimit
	accessControl.ServiceFlowLimit = param.ServiceFlowLimit
	if err := accessControl.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2007, err)
		return
	}

	if tx.Error == nil {
		tx.Commit()
	} else {
		// 如果有错误，回滚事务
		tx.Rollback()
		middleware.ResponseError(c, 2008, err)
		return
	}
	middleware.ResponseSuccess(c, "")
}

// ServiceAddTCP godoc
// @Summary 添加TCP服务
// @Description 添加TCP服务
// @Tags 服务管理
// @ID /service/addtcp
// @Accept  json
// @Produce  json
// @Param body body dto.ServiceAddTCPInput true "body"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router  /service/addtcp [post]
func (service *ServiceController) ServiceAddTCP(c *gin.Context) {
	param := &dto.ServiceAddTCPInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}

	serviceInfo := &dao.ServiceInfo{ServiceName: param.ServiceName, IsDelete: 0}
	if _, err = serviceInfo.Find(c, db, serviceInfo); err == nil {
		middleware.ResponseError(c, 2002, errors.New("服务已经存在"))
		return
	}

	tcpPort := &dao.TcpRule{Port: param.Port}
	if _, err = tcpPort.Find(c, db, tcpPort); err == nil {
		middleware.ResponseError(c, 2003, errors.New("服务端口已经存在"))
		return
	}

	if len(strings.Split(param.IPList, "\n")) != len(strings.Split(param.WeightList, "\n")) {
		middleware.ResponseError(c, 2004, errors.New("IP列表和权重列表不一致"))
		return
	}
	tx := db.Begin()
	info := &dao.ServiceInfo{
		LoadType:    public.LoadTypeTCP,
		ServiceName: param.ServiceName,
		ServiceDesc: param.ServiceDesc,
	}
	if err := info.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2005, err)
		return
	}

	loadBalance := &dao.LoadBalance{
		ServiceID:  info.ID,
		RoundType:  param.RoundType,
		IPList:     param.IPList,
		WeightList: param.WeightList,
		ForbidList: param.ForbidList,
	}
	if err := loadBalance.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2006, err)
		return
	}

	TcpRule := &dao.TcpRule{
		ServiceID: info.ID,
		Port:      param.Port,
	}
	if err := TcpRule.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2007, err)
		return
	}

	accessControl := &dao.AccessControl{
		ServiceID:         info.ID,
		OpenAuth:          param.OpenAuth,
		BlackList:         param.BlackList,
		WhiteList:         param.WhiteList,
		WhiteHostName:     param.WhiteHostName,
		ClientIPFlowLimit: param.ClientIPFlowLimit,
		ServiceFlowLimit:  param.ServiceFlowLimit,
	}
	if err := accessControl.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2008, err)
		return
	}
	if tx.Error == nil {
		tx.Commit()
	} else {
		tx.Rollback()
		middleware.ResponseError(c, 2009, tx.Error)
		return
	}
	middleware.ResponseSuccess(c, "")
}

// ServiceUpdateGRPC godoc
// @Summary 修改GRPC服务
// @Description 修改GRPC服务
// @Tags 服务管理
// @ID /service/updategrpc
// @Accept  json
// @Produce  json
// @Param body body dto.ServiceUpdateGrpcInput true "body"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router  /service/updategrpc [post]
func (service *ServiceController) ServiceUpdateGRPC(c *gin.Context) {
	param := &dto.ServiceUpdateGrpcInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	if len(strings.Split(param.IPList, "\n")) != len(strings.Split(param.WeightList, "\n")) {
		middleware.ResponseError(c, 2001, errors.New("IP列表和权重列表不一致"))
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2002, err)
		return
	}

	serviceGRPC := &dao.ServiceInfo{ID: param.ID}
	servicGRPCDetail, err := serviceGRPC.ServiceDetail(c, db, serviceGRPC)
	if err == nil {
		middleware.ResponseError(c, 2003, err)
		return
	}

	tx := db.Begin()
	info := servicGRPCDetail.Info
	info.ServiceDesc = param.ServiceDesc
	if err := info.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2004, err)
		return
	}

	loadBalance := &dao.LoadBalance{}
	if servicGRPCDetail.LoadBalance != nil {
		loadBalance = servicGRPCDetail.LoadBalance
	}
	loadBalance.ServiceID = info.ID
	loadBalance.RoundType = param.RoundType
	loadBalance.IPList = param.IPList
	loadBalance.WeightList = param.WeightList
	loadBalance.ForbidList = param.ForbidList
	if err := loadBalance.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2005, err)
		return
	}

	grpcRule := &dao.GrpcRule{}
	if servicGRPCDetail.GRPCRule != nil {
		grpcRule = servicGRPCDetail.GRPCRule
	}
	grpcRule.ServiceID = info.ID
	// grpcRule.Port = param.Port
	grpcRule.HeaderTransfor = param.HeaderTransfor
	if err := grpcRule.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2006, err)
		return
	}

	accessControl := &dao.AccessControl{}
	if servicGRPCDetail.AccessControl != nil {
		accessControl = servicGRPCDetail.AccessControl
	}
	accessControl.ServiceID = info.ID
	accessControl.OpenAuth = param.OpenAuth
	accessControl.BlackList = param.BlackList
	accessControl.WhiteList = param.WhiteList
	accessControl.WhiteHostName = param.WhiteHostName
	accessControl.ClientIPFlowLimit = param.ClientIPFlowLimit
	accessControl.ServiceFlowLimit = param.ServiceFlowLimit
	if err := accessControl.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2007, err)
		return
	}
	if tx.Error == nil {
		tx.Commit()
	} else {
		tx.Rollback()
		middleware.ResponseError(c, 2009, tx.Error)
		return
	}
	middleware.ResponseSuccess(c, "")
}

// ServiceAddGRPC godoc
// @Summary 添加GRPC服务
// @Description 添加GRPC服务
// @Tags 服务管理
// @ID /service/addgrpc
// @Accept  json
// @Produce  json
// @Param body body dto.ServiceAddGrpcInput true "body"
// @Success 200 {object} middleware.Response{data=string} "success"
// @Router  /service/addgrpc [post]
func (service *ServiceController) ServiceAddGRPC(c *gin.Context) {
	param := &dto.ServiceAddGrpcInput{}
	if err := param.BindValid(c); err != nil {
		middleware.ResponseError(c, 2000, err)
		return
	}

	db, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 2001, err)
		return
	}

	serviceInfo := &dao.ServiceInfo{ServiceName: param.ServiceName, IsDelete: 0}
	if _, err = serviceInfo.Find(c, db, serviceInfo); err == nil {
		middleware.ResponseError(c, 2002, errors.New("服务已经存在"))
		return
	}

	tcpPort := &dao.TcpRule{Port: param.Port}
	if _, err = tcpPort.Find(c, db, tcpPort); err == nil {
		middleware.ResponseError(c, 2003, errors.New("服务端口已经占用"))
		return
	}

	grpcPort := &dao.GrpcRule{Port: param.Port}
	if _, err = grpcPort.Find(c, db, grpcPort); err == nil {
		middleware.ResponseError(c, 2004, errors.New("服务端口已经占用"))
		return
	}

	if len(strings.Split(param.IPList, "\n")) != len(strings.Split(param.WeightList, "\n")) {
		middleware.ResponseError(c, 2005, errors.New("IP列表和权重列表不一致"))
		return
	}
	tx := db.Begin()
	info := &dao.ServiceInfo{
		LoadType:    public.LoadTypeGRPC,
		ServiceName: param.ServiceName,
		ServiceDesc: param.ServiceDesc,
	}
	if err := info.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2006, err)
		return
	}

	loadBalance := &dao.LoadBalance{
		ServiceID:  info.ID,
		RoundType:  param.RoundType,
		IPList:     param.IPList,
		WeightList: param.WeightList,
		ForbidList: param.ForbidList,
	}
	if err := loadBalance.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2007, err)
		return
	}

	GrpcRule := &dao.GrpcRule{
		ServiceID:      info.ID,
		Port:           param.Port,
		HeaderTransfor: param.HeaderTransfor,
	}
	if err := GrpcRule.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2008, err)
		return
	}

	accessControl := &dao.AccessControl{
		ServiceID:         info.ID,
		OpenAuth:          param.OpenAuth,
		BlackList:         param.BlackList,
		WhiteList:         param.WhiteList,
		WhiteHostName:     param.WhiteHostName,
		ClientIPFlowLimit: param.ClientIPFlowLimit,
		ServiceFlowLimit:  param.ServiceFlowLimit,
	}
	if err := accessControl.Save(c, tx); err != nil {
		tx.Rollback()
		middleware.ResponseError(c, 2009, err)
		return
	}
	if tx.Error == nil {
		tx.Commit()
	} else {
		tx.Rollback()
		middleware.ResponseError(c, 2009, tx.Error)
		return
	}
	middleware.ResponseSuccess(c, "")
}
